1. Introduction

In this notebook, I examine the relationship between utterance fluency (UF) measures and L2 speaking anxiety, addressing the following three research questions (RQs):

  • RQ1: To what extent are speed fluency measures associated with cognitive, somatic, and behavioral speaking anxiety?

  • RQ2: To what extent are breakdown fluency measures associated with cognitive, somatic, and behavioral speaking anxiety?

  • RQ3: To what extent are repair fluency measures associated with cognitive, somatic, and behavioral speaking anxiety?

In the following sections, I preprocess data, conduct preliminary analyses, and construct regression models.

The following code block loads R packages required for analyses.

pacman::p_load(
  tidyverse, here, skimr, psych, 
  PerformanceAnalytics, sjPlot, performance
)

2. Data Preprocess

This section tidies data. First of all, the following code block loads data of UF measures.

df_uf_raw <- read.csv(here("data", "processed", "uf_measures.csv"))

The current analysis focuses on the UF measures shown in Table 1.

Table 1. UF Dimension and Corresponding Measures

UF Dimension Measure
Speed Fluency (SF) Articulation Rate (AR)
Breakdown Fluency (BDF) Mid-Clause Pause Ratio (MCPR)
End-Clause Pause Ratio (ECPR)
Mid-Clause Pause Duration (MCPD)
End-Clause Pause Duration (ECPD)
Repair Fluency (RF) Disfluency Ratio

Thus, the following code block selects target measures. The code block also renames the columns filename and dysfluency_ratio to participant_id and disfluency_ratio, respectively.

df_uf_raw %>%
  select(
    filename,
    articulation_rate,
    mid_clause_pause_ratio,
    end_clause_pause_ratio,
    mid_clause_p.dur,
    end_clause_p.dur,
    dysfluency_ratio
  ) %>%
  rename(
    participant_id = filename,
    disfluency_ratio = dysfluency_ratio
  ) -> df_uf_tidy

df_uf_tidy

Next, the following code block loads data of post questionnaire about anxiety and linguistic background.

df_questionnaire_raw <- read.csv(
  here("data", "raw", "post_questionnaire.csv")
)

The following code block selects columns related to participant ID, anxiety, L2 English proficiency, and other backgrounds and renames them.

df_questionnaire_raw %>%
  select(
    参加者IDを入力してください.半角..,
    英語を話すとき.私は言葉を間違えてしまうのではとしばしば心配になる.,
    英語を話すとき.私は自分の話し方が他人より劣っているのではとしばしば心配になる.,
    英語を話し始めるとすぐに.私は自分自身のことを表現できないのではと心配になり始める.,
    英語を話すとき.私はドキドキすることがよくある.,
    英語を話すとき.私は緊張でびくびくすることがよくある.,
    英語を話すとき.私はよく汗をかいたり.発汗する.,
    英語スピーキングの練習をするとき.私はしばしば.すぐに投げ出してしまう.,
    私は英語スピーキングの練習の手を抜くことが多い.,
    私は普段.極力英語を話さないようにしている.,
    お持ちでしたら.英検のスコアを記入してください.,
    お持ちでしたら.IELTS..Overall..のスコアを記入してください.,
    お持ちでしたら.TOEFL.iBT.のスコアを記入してください.,
    お持ちでしたら.TOEIC.のスコアを記入してください.,
    性別,
    年齢
  ) %>%
  rename(
    participant_id = 参加者IDを入力してください.半角..,
    cognitive_anxiety_1 = 英語を話すとき.私は言葉を間違えてしまうのではとしばしば心配になる.,
    cognitive_anxiety_2 = 英語を話すとき.私は自分の話し方が他人より劣っているのではとしばしば心配になる.,
    cognitive_anxiety_3 = 英語を話し始めるとすぐに.私は自分自身のことを表現できないのではと心配になり始める.,
    somatic_anxiety_1 = 英語を話すとき.私はドキドキすることがよくある.,
    somatic_anxiety_2 = 英語を話すとき.私は緊張でびくびくすることがよくある.,
    somatic_anxiety_3 = 英語を話すとき.私はよく汗をかいたり.発汗する.,
    behavioral_anxiety_1 = 英語スピーキングの練習をするとき.私はしばしば.すぐに投げ出してしまう.,
    behavioral_anxiety_2 = 私は英語スピーキングの練習の手を抜くことが多い.,
    behavioral_anxiety_3 = 私は普段.極力英語を話さないようにしている.,
    IELTS = お持ちでしたら.IELTS..Overall..のスコアを記入してください.,
    TOEFL_IBT = お持ちでしたら.TOEFL.iBT.のスコアを記入してください.,
    TOEIC = お持ちでしたら.TOEIC.のスコアを記入してください.,
    eiken = お持ちでしたら.英検のスコアを記入してください.,
    sex = 性別,
    age = 年齢
  ) %>%
  mutate(
    sex = str_replace_all(sex, "男性", "male"),
    sex = str_replace_all(sex, "女性", "female"),
    eiken = str_replace_all(eiken, "準1級", "1.5"),
    eiken = str_replace_all(eiken, "準1級", "1.5"),
    eiken = str_replace_all(eiken, "2級", "2"),
    eiken = str_replace_all(eiken, "1級", "1"),
    eiken = str_replace_all(eiken, "英検4級", "4"),
    eiken = as.numeric(eiken)
  ) -> df_questionnaire_tidy

df_questionnaire_tidy

3. Preliminary Analysis

3.1. Participant Background

The following code block calculates the descriptive statistics of participants’ age.

df_questionnaire_tidy %>%
  select(age) %>%
  skim()
── Data Summary ────────────────────────
                           Values    
Name                       Piped data
Number of rows             10        
Number of columns          1         
_______________________              
Column type frequency:               
  numeric                  1         
________________________             
Group variables            None      

The result showed that participants’ age was ranged \([20, 38]\), and their mean and SD were \(28.8\) and \(5.613\).

The following code block counts sex of participants.

df_questionnaire_tidy %>%
  group_by(sex) %>%
  summarize(N = n())

The result indicated that there were equal number of male and female participants.

3.2. Proficiency Levels

The following code block converts L2 English assessment scores to CEFR.

cefr_levels = c("A1", "A2", "B1", "B2", "C1", "C2")

df_questionnaire_tidy %>%
  select(participant_id, TOEFL_IBT, IELTS, TOEIC, eiken) %>%
  mutate(
    TOEFL_IBT = case_when(
      TOEFL_IBT >= 114 ~ "C2",
      TOEFL_IBT >= 95 ~ "C1",
      TOEFL_IBT >= 72 ~ "B2"
    ),
    IELTS = case_when(
      IELTS >= 7 ~ "C1"
    ),
    TOEIC = case_when(
      TOEIC >= 945 ~ "C1",
      TOEIC >= 785 ~ "B1",
      TOEIC >= 550 ~ "B2"
    ),
    eiken = case_when(
      eiken >= 3 ~ "A1",
      eiken >= 2 ~ "B1",
      eiken >= 1.5 ~ "B2",
      eiken >= 1 ~ "C1"
    )
  ) %>%
  mutate(
    TOEFL_IBT = factor(TOEFL_IBT, levels = cefr_levels, order = T),
    IELTS = factor(IELTS, levels = cefr_levels, order = T),
    TOEIC = factor(TOEIC, levels = cefr_levels, order = T),
    eiken = factor(eiken, levels = cefr_levels, order = T)
  ) %>% 
  replace_na(list(
    TOEFL_IBT = "A1",
    IELTS = "A1",
    TOEIC = "A1",
    eiken = "A1"
  )) %>%
  group_by(participant_id) %>%
  summarize(CEFR = max(TOEFL_IBT, IELTS, TOEIC, eiken)) %>%
  group_by(CEFR) %>%
  summarize(N = n())

The result suggested that most participants were advanced-level L2 English learners (\(N=6\)), while other four participants were intermediate-level English learners.

3.3. UF Measures

The following code block calculates the descriptive statistics of UF measures.

df_uf_tidy %>%
  select(-c(participant_id)) %>%
  skim()
── Data Summary ────────────────────────
                           Values    
Name                       Piped data
Number of rows             10        
Number of columns          6         
_______________________              
Column type frequency:               
  numeric                  6         
________________________             
Group variables            None      

3.4. Speaking Anxiety

The following code blocks calculate the reliability of anxiety questionnaire answers in terms of Cronbach’s \(\alpha\).

3.4.1. Reliability of Cognitive Anxiety

df_questionnaire_tidy %>% 
  select(
    cognitive_anxiety_1,
    cognitive_anxiety_2,
    cognitive_anxiety_3
  ) %>%
  alpha()

Reliability analysis   
Call: alpha(x = .)

 

    95% confidence boundaries 

 Reliability if an item is dropped:

 Item statistics 

Non missing response frequency for each item
                      1   2   3   4   5 miss
cognitive_anxiety_1 0.0 0.3 0.1 0.3 0.3    0
cognitive_anxiety_2 0.1 0.1 0.0 0.6 0.2    0
cognitive_anxiety_3 0.2 0.3 0.0 0.2 0.3    0

The Cornbach’s \(\alpha\) of cognitive anxiety questionnaires was \(.747\), indicating an acceptable internal consistency

3.4.2. Reliability of Somatic Anxiety

df_questionnaire_tidy %>% 
  select(
    somatic_anxiety_1,
    somatic_anxiety_2,
    somatic_anxiety_3
  ) %>%
  alpha()

Reliability analysis   
Call: alpha(x = .)

 

    95% confidence boundaries 

 Reliability if an item is dropped:

 Item statistics 

Non missing response frequency for each item
                    1   2   3   4   5 miss
somatic_anxiety_1 0.2 0.3 0.1 0.2 0.2    0
somatic_anxiety_2 0.3 0.2 0.2 0.0 0.3    0
somatic_anxiety_3 0.3 0.3 0.0 0.4 0.0    0

The Cornbach’s \(\alpha\) of somatic anxiety questionnaires was \(.900\), indicating a excellent internal consistency.

3.4.3. Behavioral Anxiety

df_questionnaire_tidy %>% 
  select(
    behavioral_anxiety_1,
    behavioral_anxiety_2,
    behavioral_anxiety_3
  ) %>%
  alpha()

Reliability analysis   
Call: alpha(x = .)

 

    95% confidence boundaries 

 Reliability if an item is dropped:

 Item statistics 

Non missing response frequency for each item
                       1   2   3   4   5 miss
behavioral_anxiety_1 0.2 0.4 0.2 0.1 0.1    0
behavioral_anxiety_2 0.2 0.3 0.1 0.3 0.1    0
behavioral_anxiety_3 0.4 0.3 0.2 0.1 0.0    0

The Cornbach’s \(\alpha\) of somatic anxiety questionnaires was \(.814\), indicating a good internal consistency.

3.5. Correlations

This subsection conducts correlation analyses between UF measures and speaking anxiety. Before the analyses, the following code block calculates three anxiety scores by summing items and joins the two dataframes.

df_questionnaire_tidy %>%
  group_by(participant_id) %>%
  summarize(
    cognitive_anxiety = sum(
      cognitive_anxiety_1, cognitive_anxiety_2, cognitive_anxiety_3
    ),
    somatic_anxiety = sum(
      somatic_anxiety_1, somatic_anxiety_2, somatic_anxiety_3
    ),
    behavioral_anxiety = sum(
      behavioral_anxiety_1, behavioral_anxiety_2, behavioral_anxiety_3
    )
  ) %>% 
  inner_join(
    df_uf_tidy, by = "participant_id"
  ) -> df_uf_anxiety

df_uf_anxiety

3.5.1. Correlations Among Anxiety Scores

The following code block generates a correlation matrix of three anxiety scores.

df_uf_anxiety %>%
  select(
    cognitive_anxiety,
    somatic_anxiety,
    behavioral_anxiety
  ) %>%
  chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result showed that significant strong correlation between cognitive and somatic anxiety (\(r=.78\)). In addition, there was slightly significant medium correlation between somatic and behavioral anxiety (\(r=.59\)). Meanwhile, there was small correlation between cognitive and behavioral anxiety (\(r=.48\)), but statistical significance was not found.

3.5.2. Correlations Between UF Measures and Cognitive Anxiety

The following code block generates a correlation matrix of UF measures and cognitive anxiety.

df_uf_anxiety %>%
  select(-c(
    participant_id, 
    somatic_anxiety, 
    behavioral_anxiety
  )) %>%
  chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result showed significant large correlation between cognitive anxiety and ECPR, suggesting that participants produced end-clause pauses more frequently when cognitive anxiety was lower.

3.5.3. Correlations Between UF Measures and Somatic Anxiety

The following code block generates a correlation matrix of UF measures and somatic anxiety.

df_uf_anxiety %>%
  select(-c(
    participant_id, 
    cognitive_anxiety, 
    behavioral_anxiety
  )) %>%
  chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result did not show significant correlations between somatic anxiety and UF measures.

3.5.4. Correlations Between UF Measures and Behavioral Anxiety

The following code block generates a correlation matrix of UF measures and behavioral anxiety.

df_uf_anxiety %>%
  select(-c(
    participant_id, 
    cognitive_anxiety, 
    somatic_anxiety
  )) %>%
  chart.Correlation(histogram = T, method = "pearson", pch = 19)
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter
Warning in par(usr) : argument 1 does not name a graphical parameter

The result identified significant large correlations between behavioral anxiety and MCPD (\(r=-.76\)) and ECPD (\(r=.79\)), suggesting that participants who perceived lower behavioral anxiety generate longer MCPD and ECPD.


4. Regression Analyses

4.1. SF ~ Speaking Anxiety

The following code block constructs a regression model between AR and speaking anxiety.

model_ar <- lm(
  articulation_rate ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
  df_uf_anxiety
)

The following code block shows the result.

tab_model(model_ar, digits = 3)

The result did not show significant relationship between three anxiety scores and AR.

To examine the reliability of the current model, the following code block conducts post-hoc analysis of regression assumptions.

check_model(model_ar)

The results suggested that the current model could be reliable.

4.2. BDF ~ Speaking Anxiety

4.2.1. MCPR ~ Speaking Anxiety

The following code block constructs a regression model between MCPR and speaking anxiety.

model_mcpr <- lm(
  mid_clause_pause_ratio ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
  df_uf_anxiety
)

The following code block shows the result.

tab_model(model_mcpr, digits = 3)

The result did not show significant relationship between three anxiety scores and MCPR.

To examine the reliability of the current model, the following code block conducts post-hoc analysis of regression assumptions.

check_model(model_mcpr)

The results suggested that the current model could be less reliable because the model could be affected by an outlier.

4.2.2. ECPR ~ Speaking Anxiety

The following code block constructs a regression model between ECPR and speaking anxiety.

model_ecpr <- lm(
  end_clause_pause_ratio ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
  df_uf_anxiety
)

The following code block shows the result.

tab_model(model_ecpr, digits = 3)

The result showed slightly significant relationship between cognitive anxiety and ECPR (\(p=.081\)). The slope was \(-.003\) and suggested that ECPR decreased \(.003\) when cognitive anxiety increased \(1\).

To examine the reliability of the current model, the following code block conducts post-hoc analysis of regression assumptions.

check_model(model_ecpr)

The results suggested that the current model could be reliable.

4.2.3. MCPD ~ Speaking Anxiety

The following code block constructs a regression model between MCPD and speaking anxiety.

model_mcpd <- lm(
  mid_clause_p.dur ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
  df_uf_anxiety
)

The following code block shows the result.

tab_model(model_mcpd, digits = 3)

The result showed a significant link between behavioral anxiety and MCPD (\(p=.025\)). The slope was \(-.074\), suggesting that MCPD became \(.074\) shorter when behavioral anxiety score increased \(1\).

To examine the reliability of the current model, the following code block conducts post-hoc analysis of regression assumptions.

check_model(model_mcpd)

The results suggested that the current model could be reliable.

4.2.4. ECPD ~ Speaking Anxiety

The following code block constructs a regression model between AR and speaking anxiety.

model_enpd <- lm(
  end_clause_p.dur ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
  df_uf_anxiety
)

The following code block shows the result.

tab_model(model_enpd, digits = 3)

The result showed a significant link between behavioral anxiety and MCPD (\(p=.020\)). The slope was \(-.072\), suggesting that ECPD became \(.072\) shorter when behavioral anxiety score increased \(1\).

To examine the reliability of the current model, the following code block conducts post-hoc analysis of regression assumptions.

check_model(model_enpd)

The results suggested that the current model could be reliable.

4.3. RF ~ Speaking Anxiety

The following code block constructs a regression model between DR and speaking anxiety.

model_dr <- lm(
  disfluency_ratio ~ cognitive_anxiety + somatic_anxiety + behavioral_anxiety,
  df_uf_anxiety
)

The following code block shows the result.

tab_model(model_dr, digits = 3)

The result did not show significant relationship between three anxiety scores and DR.

To examine the reliability of the current model, the following code block conducts post-hoc analysis of regression assumptions.

check_model(model_dr)

Quitting from lines 526-527 [unnamed-chunk-35] (final_report_analysis.Rmd)

The results suggested that the current model could be less reliable because the model could be affected by an outlier.

LS0tCnRpdGxlOiAnSW50cm9SOiBGaW5hbCBSZXBvcnQgQW5hbHlzaXMnCmF1dGhvcjogIlJ5dWtpIE1hdHN1dXJhIgpkYXRlOiAiMjAyNC8xMS8yNyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQotLS0KCiMjIDEuIEludHJvZHVjdGlvbgoKSW4gdGhpcyBub3RlYm9vaywgSSBleGFtaW5lIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB1dHRlcmFuY2UgZmx1ZW5jeSAoVUYpIG1lYXN1cmVzIGFuZCBMMiBzcGVha2luZyBhbnhpZXR5LCBhZGRyZXNzaW5nIHRoZSBmb2xsb3dpbmcgdGhyZWUgcmVzZWFyY2ggcXVlc3Rpb25zIChSUXMpOgoKLSAgIFJRMTogVG8gd2hhdCBleHRlbnQgYXJlIHNwZWVkIGZsdWVuY3kgbWVhc3VyZXMgYXNzb2NpYXRlZCB3aXRoIGNvZ25pdGl2ZSwgc29tYXRpYywgYW5kIGJlaGF2aW9yYWwgc3BlYWtpbmcgYW54aWV0eT8KCi0gICBSUTI6IFRvIHdoYXQgZXh0ZW50IGFyZSBicmVha2Rvd24gZmx1ZW5jeSBtZWFzdXJlcyBhc3NvY2lhdGVkIHdpdGggY29nbml0aXZlLCBzb21hdGljLCBhbmQgYmVoYXZpb3JhbCBzcGVha2luZyBhbnhpZXR5PwoKLSAgIFJRMzogVG8gd2hhdCBleHRlbnQgYXJlIHJlcGFpciBmbHVlbmN5IG1lYXN1cmVzIGFzc29jaWF0ZWQgd2l0aCBjb2duaXRpdmUsIHNvbWF0aWMsIGFuZCBiZWhhdmlvcmFsIHNwZWFraW5nIGFueGlldHk/CgpJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb25zLCBJIHByZXByb2Nlc3MgZGF0YSwgY29uZHVjdCBwcmVsaW1pbmFyeSBhbmFseXNlcywgYW5kIGNvbnN0cnVjdCByZWdyZXNzaW9uIG1vZGVscy4KClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBsb2FkcyBSIHBhY2thZ2VzIHJlcXVpcmVkIGZvciBhbmFseXNlcy4KCmBgYHtyfQpwYWNtYW46OnBfbG9hZCgKICB0aWR5dmVyc2UsIGhlcmUsIHNraW1yLCBwc3ljaCwgCiAgUGVyZm9ybWFuY2VBbmFseXRpY3MsIHNqUGxvdCwgcGVyZm9ybWFuY2UKKQpgYGAKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgMi4gRGF0YSBQcmVwcm9jZXNzCgpUaGlzIHNlY3Rpb24gdGlkaWVzIGRhdGEuIEZpcnN0IG9mIGFsbCwgdGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGxvYWRzIGRhdGEgb2YgVUYgbWVhc3VyZXMuCgpgYGB7cn0KZGZfdWZfcmF3IDwtIHJlYWQuY3N2KGhlcmUoImRhdGEiLCAicHJvY2Vzc2VkIiwgInVmX21lYXN1cmVzLmNzdiIpKQpgYGAKClRoZSBjdXJyZW50IGFuYWx5c2lzIGZvY3VzZXMgb24gdGhlIFVGIG1lYXN1cmVzIHNob3duIGluIFRhYmxlIDEuCgpUYWJsZSAxLiBVRiBEaW1lbnNpb24gYW5kIENvcnJlc3BvbmRpbmcgTWVhc3VyZXMKCnwgVUYgRGltZW5zaW9uICAgICAgICAgICAgfCBNZWFzdXJlICAgICAgICAgICAgICAgICAgICAgICAgICB8CnwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18CnwgU3BlZWQgRmx1ZW5jeSAoU0YpICAgICAgfCBBcnRpY3VsYXRpb24gUmF0ZSAoQVIpICAgICAgICAgICB8CnwgQnJlYWtkb3duIEZsdWVuY3kgKEJERikgfCBNaWQtQ2xhdXNlIFBhdXNlIFJhdGlvIChNQ1BSKSAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbmQtQ2xhdXNlIFBhdXNlIFJhdGlvIChFQ1BSKSAgICB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgfCBNaWQtQ2xhdXNlIFBhdXNlIER1cmF0aW9uIChNQ1BEKSB8CnwgICAgICAgICAgICAgICAgICAgICAgICAgfCBFbmQtQ2xhdXNlIFBhdXNlIER1cmF0aW9uIChFQ1BEKSB8CnwgUmVwYWlyIEZsdWVuY3kgKFJGKSAgICAgfCBEaXNmbHVlbmN5IFJhdGlvICAgICAgICAgICAgICAgICB8CgpUaHVzLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgc2VsZWN0cyB0YXJnZXQgbWVhc3VyZXMuIFRoZSBjb2RlIGJsb2NrIGFsc28gcmVuYW1lcyB0aGUgY29sdW1ucyBgZmlsZW5hbWVgIGFuZCBgZHlzZmx1ZW5jeV9yYXRpb2AgdG8gYHBhcnRpY2lwYW50X2lkYCBhbmQgYGRpc2ZsdWVuY3lfcmF0aW9gLCByZXNwZWN0aXZlbHkuCgpgYGB7cn0KZGZfdWZfcmF3ICU+JQogIHNlbGVjdCgKICAgIGZpbGVuYW1lLAogICAgYXJ0aWN1bGF0aW9uX3JhdGUsCiAgICBtaWRfY2xhdXNlX3BhdXNlX3JhdGlvLAogICAgZW5kX2NsYXVzZV9wYXVzZV9yYXRpbywKICAgIG1pZF9jbGF1c2VfcC5kdXIsCiAgICBlbmRfY2xhdXNlX3AuZHVyLAogICAgZHlzZmx1ZW5jeV9yYXRpbwogICkgJT4lCiAgcmVuYW1lKAogICAgcGFydGljaXBhbnRfaWQgPSBmaWxlbmFtZSwKICAgIGRpc2ZsdWVuY3lfcmF0aW8gPSBkeXNmbHVlbmN5X3JhdGlvCiAgKSAtPiBkZl91Zl90aWR5CgpkZl91Zl90aWR5CmBgYAoKTmV4dCwgdGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGxvYWRzIGRhdGEgb2YgcG9zdCBxdWVzdGlvbm5haXJlIGFib3V0IGFueGlldHkgYW5kIGxpbmd1aXN0aWMgYmFja2dyb3VuZC4KCmBgYHtyfQpkZl9xdWVzdGlvbm5haXJlX3JhdyA8LSByZWFkLmNzdigKICBoZXJlKCJkYXRhIiwgInJhdyIsICJwb3N0X3F1ZXN0aW9ubmFpcmUuY3N2IikKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzZWxlY3RzIGNvbHVtbnMgcmVsYXRlZCB0byBwYXJ0aWNpcGFudCBJRCwgYW54aWV0eSwgTDIgRW5nbGlzaCBwcm9maWNpZW5jeSwgYW5kIG90aGVyIGJhY2tncm91bmRzIGFuZCByZW5hbWVzIHRoZW0uCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV9yYXcgJT4lCiAgc2VsZWN0KAogICAg5Y+C5Yqg6ICFSUTjgpLlhaXlipvjgZfjgabjgY/jgaDjgZXjgYQu5Y2K6KeSLi4sCiAgICDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv6KiA6JGJ44KS6ZaT6YGV44GI44Gm44GX44G+44GG44Gu44Gn44Gv44Go44GX44Gw44GX44Gw5b+D6YWN44Gr44Gq44KLLiwKICAgIOiLseiqnuOCkuipseOBmeOBqOOBjS7np4Hjga/oh6rliIbjga7oqbHjgZfmlrnjgYzku5bkurrjgojjgorliqPjgaPjgabjgYTjgovjga7jgafjga/jgajjgZfjgbDjgZfjgbDlv4PphY3jgavjgarjgosuLAogICAg6Iux6Kqe44KS6Kmx44GX5aeL44KB44KL44Go44GZ44GQ44GrLuengeOBr+iHquWIhuiHqui6q+OBruOBk+OBqOOCkuihqOePvuOBp+OBjeOBquOBhOOBruOBp+OBr+OBqOW/g+mFjeOBq+OBquOCiuWni+OCgeOCiy4sCiAgICDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv44OJ44Kt44OJ44Kt44GZ44KL44GT44Go44GM44KI44GP44GC44KLLiwKICAgIOiLseiqnuOCkuipseOBmeOBqOOBjS7np4Hjga/nt4rlvLXjgafjgbPjgY/jgbPjgY/jgZnjgovjgZPjgajjgYzjgojjgY/jgYLjgosuLAogICAg6Iux6Kqe44KS6Kmx44GZ44Go44GNLuengeOBr+OCiOOBj+axl+OCkuOBi+OBhOOBn+OCii7nmbrmsZfjgZnjgosuLAogICAg6Iux6Kqe44K544OU44O844Kt44Oz44Kw44Gu57e057+S44KS44GZ44KL44Go44GNLuengeOBr+OBl+OBsOOBl+OBsC7jgZnjgZDjgavmipXjgZLlh7rjgZfjgabjgZfjgb7jgYYuLAogICAg56eB44Gv6Iux6Kqe44K544OU44O844Kt44Oz44Kw44Gu57e057+S44Gu5omL44KS5oqc44GP44GT44Go44GM5aSa44GELiwKICAgIOengeOBr+aZruautS7mpbXlipvoi7Hoqp7jgpLoqbHjgZXjgarjgYTjgojjgYbjgavjgZfjgabjgYTjgosuLAogICAg44GK5oyB44Gh44Gn44GX44Gf44KJLuiLseaknOOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICDjgYrmjIHjgaHjgafjgZfjgZ/jgokuSUVMVFMuLk92ZXJhbGwuLuOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICDjgYrmjIHjgaHjgafjgZfjgZ/jgokuVE9FRkwuaUJULuOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICDjgYrmjIHjgaHjgafjgZfjgZ/jgokuVE9FSUMu44Gu44K544Kz44Ki44KS6KiY5YWl44GX44Gm44GP44Gg44GV44GELiwKICAgIOaAp+WIpSwKICAgIOW5tOm9ogogICkgJT4lCiAgcmVuYW1lKAogICAgcGFydGljaXBhbnRfaWQgPSDlj4LliqDogIVJROOCkuWFpeWKm+OBl+OBpuOBj+OBoOOBleOBhC7ljYrop5IuLiwKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzEgPSDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv6KiA6JGJ44KS6ZaT6YGV44GI44Gm44GX44G+44GG44Gu44Gn44Gv44Go44GX44Gw44GX44Gw5b+D6YWN44Gr44Gq44KLLiwKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzIgPSDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv6Ieq5YiG44Gu6Kmx44GX5pa544GM5LuW5Lq644KI44KK5Yqj44Gj44Gm44GE44KL44Gu44Gn44Gv44Go44GX44Gw44GX44Gw5b+D6YWN44Gr44Gq44KLLiwKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzMgPSDoi7Hoqp7jgpLoqbHjgZflp4vjgoHjgovjgajjgZnjgZDjgasu56eB44Gv6Ieq5YiG6Ieq6Lqr44Gu44GT44Go44KS6KGo54++44Gn44GN44Gq44GE44Gu44Gn44Gv44Go5b+D6YWN44Gr44Gq44KK5aeL44KB44KLLiwKICAgIHNvbWF0aWNfYW54aWV0eV8xID0g6Iux6Kqe44KS6Kmx44GZ44Go44GNLuengeOBr+ODieOCreODieOCreOBmeOCi+OBk+OBqOOBjOOCiOOBj+OBguOCiy4sCiAgICBzb21hdGljX2FueGlldHlfMiA9IOiLseiqnuOCkuipseOBmeOBqOOBjS7np4Hjga/nt4rlvLXjgafjgbPjgY/jgbPjgY/jgZnjgovjgZPjgajjgYzjgojjgY/jgYLjgosuLAogICAgc29tYXRpY19hbnhpZXR5XzMgPSDoi7Hoqp7jgpLoqbHjgZnjgajjgY0u56eB44Gv44KI44GP5rGX44KS44GL44GE44Gf44KKLueZuuaxl+OBmeOCiy4sCiAgICBiZWhhdmlvcmFsX2FueGlldHlfMSA9IOiLseiqnuOCueODlOODvOOCreODs+OCsOOBrue3tOe/kuOCkuOBmeOCi+OBqOOBjS7np4Hjga/jgZfjgbDjgZfjgbAu44GZ44GQ44Gr5oqV44GS5Ye644GX44Gm44GX44G+44GGLiwKICAgIGJlaGF2aW9yYWxfYW54aWV0eV8yID0g56eB44Gv6Iux6Kqe44K544OU44O844Kt44Oz44Kw44Gu57e057+S44Gu5omL44KS5oqc44GP44GT44Go44GM5aSa44GELiwKICAgIGJlaGF2aW9yYWxfYW54aWV0eV8zID0g56eB44Gv5pmu5q61LualteWKm+iLseiqnuOCkuipseOBleOBquOBhOOCiOOBhuOBq+OBl+OBpuOBhOOCiy4sCiAgICBJRUxUUyA9IOOBiuaMgeOBoeOBp+OBl+OBn+OCiS5JRUxUUy4uT3ZlcmFsbC4u44Gu44K544Kz44Ki44KS6KiY5YWl44GX44Gm44GP44Gg44GV44GELiwKICAgIFRPRUZMX0lCVCA9IOOBiuaMgeOBoeOBp+OBl+OBn+OCiS5UT0VGTC5pQlQu44Gu44K544Kz44Ki44KS6KiY5YWl44GX44Gm44GP44Gg44GV44GELiwKICAgIFRPRUlDID0g44GK5oyB44Gh44Gn44GX44Gf44KJLlRPRUlDLuOBruOCueOCs+OCouOCkuiomOWFpeOBl+OBpuOBj+OBoOOBleOBhC4sCiAgICBlaWtlbiA9IOOBiuaMgeOBoeOBp+OBl+OBn+OCiS7oi7HmpJzjga7jgrnjgrPjgqLjgpLoqJjlhaXjgZfjgabjgY/jgaDjgZXjgYQuLAogICAgc2V4ID0g5oCn5YilLAogICAgYWdlID0g5bm06b2iCiAgKSAlPiUKICBtdXRhdGUoCiAgICBzZXggPSBzdHJfcmVwbGFjZV9hbGwoc2V4LCAi55S35oCnIiwgIm1hbGUiKSwKICAgIHNleCA9IHN0cl9yZXBsYWNlX2FsbChzZXgsICLlpbPmgKciLCAiZmVtYWxlIiksCiAgICBlaWtlbiA9IHN0cl9yZXBsYWNlX2FsbChlaWtlbiwgIua6ljHntJoiLCAiMS41IiksCiAgICBlaWtlbiA9IHN0cl9yZXBsYWNlX2FsbChlaWtlbiwgIua6lu+8kee0miIsICIxLjUiKSwKICAgIGVpa2VuID0gc3RyX3JlcGxhY2VfYWxsKGVpa2VuLCAiMue0miIsICIyIiksCiAgICBlaWtlbiA9IHN0cl9yZXBsYWNlX2FsbChlaWtlbiwgIjHntJoiLCAiMSIpLAogICAgZWlrZW4gPSBzdHJfcmVwbGFjZV9hbGwoZWlrZW4sICLoi7HmpJw057SaIiwgIjQiKSwKICAgIGVpa2VuID0gYXMubnVtZXJpYyhlaWtlbikKICApIC0+IGRmX3F1ZXN0aW9ubmFpcmVfdGlkeQoKZGZfcXVlc3Rpb25uYWlyZV90aWR5CmBgYAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyAzLiBQcmVsaW1pbmFyeSBBbmFseXNpcwoKIyMjIDMuMS4gUGFydGljaXBhbnQgQmFja2dyb3VuZAoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGNhbGN1bGF0ZXMgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3Mgb2YgcGFydGljaXBhbnRzJyBhZ2UuCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIHNlbGVjdChhZ2UpICU+JQogIHNraW0oKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIHRoYXQgcGFydGljaXBhbnRzJyBhZ2Ugd2FzIHJhbmdlZCAkWzIwLCAzOF0kLCBhbmQgdGhlaXIgbWVhbiBhbmQgU0Qgd2VyZSAkMjguOCQgYW5kICQ1LjYxMyQuCgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY291bnRzIHNleCBvZiBwYXJ0aWNpcGFudHMuCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIGdyb3VwX2J5KHNleCkgJT4lCiAgc3VtbWFyaXplKE4gPSBuKCkpCmBgYAoKVGhlIHJlc3VsdCBpbmRpY2F0ZWQgdGhhdCB0aGVyZSB3ZXJlIGVxdWFsIG51bWJlciBvZiBtYWxlIGFuZCBmZW1hbGUgcGFydGljaXBhbnRzLgoKIyMjIDMuMi4gUHJvZmljaWVuY3kgTGV2ZWxzCgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29udmVydHMgTDIgRW5nbGlzaCBhc3Nlc3NtZW50IHNjb3JlcyB0byBDRUZSLgoKYGBge3J9CmNlZnJfbGV2ZWxzID0gYygiQTEiLCAiQTIiLCAiQjEiLCAiQjIiLCAiQzEiLCAiQzIiKQoKZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudF9pZCwgVE9FRkxfSUJULCBJRUxUUywgVE9FSUMsIGVpa2VuKSAlPiUKICBtdXRhdGUoCiAgICBUT0VGTF9JQlQgPSBjYXNlX3doZW4oCiAgICAgIFRPRUZMX0lCVCA+PSAxMTQgfiAiQzIiLAogICAgICBUT0VGTF9JQlQgPj0gOTUgfiAiQzEiLAogICAgICBUT0VGTF9JQlQgPj0gNzIgfiAiQjIiCiAgICApLAogICAgSUVMVFMgPSBjYXNlX3doZW4oCiAgICAgIElFTFRTID49IDcgfiAiQzEiCiAgICApLAogICAgVE9FSUMgPSBjYXNlX3doZW4oCiAgICAgIFRPRUlDID49IDk0NSB+ICJDMSIsCiAgICAgIFRPRUlDID49IDc4NSB+ICJCMSIsCiAgICAgIFRPRUlDID49IDU1MCB+ICJCMiIKICAgICksCiAgICBlaWtlbiA9IGNhc2Vfd2hlbigKICAgICAgZWlrZW4gPj0gMyB+ICJBMSIsCiAgICAgIGVpa2VuID49IDIgfiAiQjEiLAogICAgICBlaWtlbiA+PSAxLjUgfiAiQjIiLAogICAgICBlaWtlbiA+PSAxIH4gIkMxIgogICAgKQogICkgJT4lCiAgbXV0YXRlKAogICAgVE9FRkxfSUJUID0gZmFjdG9yKFRPRUZMX0lCVCwgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCksCiAgICBJRUxUUyA9IGZhY3RvcihJRUxUUywgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCksCiAgICBUT0VJQyA9IGZhY3RvcihUT0VJQywgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCksCiAgICBlaWtlbiA9IGZhY3RvcihlaWtlbiwgbGV2ZWxzID0gY2Vmcl9sZXZlbHMsIG9yZGVyID0gVCkKICApICU+JSAKICByZXBsYWNlX25hKGxpc3QoCiAgICBUT0VGTF9JQlQgPSAiQTEiLAogICAgSUVMVFMgPSAiQTEiLAogICAgVE9FSUMgPSAiQTEiLAogICAgZWlrZW4gPSAiQTEiCiAgKSkgJT4lCiAgZ3JvdXBfYnkocGFydGljaXBhbnRfaWQpICU+JQogIHN1bW1hcml6ZShDRUZSID0gbWF4KFRPRUZMX0lCVCwgSUVMVFMsIFRPRUlDLCBlaWtlbikpICU+JQogIGdyb3VwX2J5KENFRlIpICU+JQogIHN1bW1hcml6ZShOID0gbigpKQpgYGAKClRoZSByZXN1bHQgc3VnZ2VzdGVkIHRoYXQgbW9zdCBwYXJ0aWNpcGFudHMgd2VyZSBhZHZhbmNlZC1sZXZlbCBMMiBFbmdsaXNoIGxlYXJuZXJzICgkTj02JCksIHdoaWxlIG90aGVyIGZvdXIgcGFydGljaXBhbnRzIHdlcmUgaW50ZXJtZWRpYXRlLWxldmVsIEVuZ2xpc2ggbGVhcm5lcnMuCgojIyMgMy4zLiBVRiBNZWFzdXJlcwoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGNhbGN1bGF0ZXMgdGhlIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3Mgb2YgVUYgbWVhc3VyZXMuCgpgYGB7cn0KZGZfdWZfdGlkeSAlPiUKICBzZWxlY3QoLWMocGFydGljaXBhbnRfaWQpKSAlPiUKICBza2ltKCkKYGBgCgojIyMgMy40LiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2tzIGNhbGN1bGF0ZSB0aGUgcmVsaWFiaWxpdHkgb2YgYW54aWV0eSBxdWVzdGlvbm5haXJlIGFuc3dlcnMgaW4gdGVybXMgb2YgQ3JvbmJhY2gncyAkXGFscGhhJC4KCiMjIyMgKjMuNC4xLiBSZWxpYWJpbGl0eSBvZiBDb2duaXRpdmUgQW54aWV0eSoKCmBgYHtyfQpkZl9xdWVzdGlvbm5haXJlX3RpZHkgJT4lIAogIHNlbGVjdCgKICAgIGNvZ25pdGl2ZV9hbnhpZXR5XzEsCiAgICBjb2duaXRpdmVfYW54aWV0eV8yLAogICAgY29nbml0aXZlX2FueGlldHlfMwogICkgJT4lCiAgYWxwaGEoKQpgYGAKClRoZSBDb3JuYmFjaCdzICRcYWxwaGEkIG9mIGNvZ25pdGl2ZSBhbnhpZXR5IHF1ZXN0aW9ubmFpcmVzIHdhcyAkLjc0NyQsIGluZGljYXRpbmcgYW4gYWNjZXB0YWJsZSBpbnRlcm5hbCBjb25zaXN0ZW5jeQoKIyMjIyAqMy40LjIuIFJlbGlhYmlsaXR5IG9mIFNvbWF0aWMgQW54aWV0eSoKCmBgYHtyfQpkZl9xdWVzdGlvbm5haXJlX3RpZHkgJT4lIAogIHNlbGVjdCgKICAgIHNvbWF0aWNfYW54aWV0eV8xLAogICAgc29tYXRpY19hbnhpZXR5XzIsCiAgICBzb21hdGljX2FueGlldHlfMwogICkgJT4lCiAgYWxwaGEoKQpgYGAKClRoZSBDb3JuYmFjaCdzICRcYWxwaGEkIG9mIHNvbWF0aWMgYW54aWV0eSBxdWVzdGlvbm5haXJlcyB3YXMgJC45MDAkLCBpbmRpY2F0aW5nIGEgZXhjZWxsZW50IGludGVybmFsIGNvbnNpc3RlbmN5LgoKIyMjIyAzLjQuMy4gQmVoYXZpb3JhbCBBbnhpZXR5CgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JSAKICBzZWxlY3QoCiAgICBiZWhhdmlvcmFsX2FueGlldHlfMSwKICAgIGJlaGF2aW9yYWxfYW54aWV0eV8yLAogICAgYmVoYXZpb3JhbF9hbnhpZXR5XzMKICApICU+JQogIGFscGhhKCkKYGBgCgpUaGUgQ29ybmJhY2gncyAkXGFscGhhJCBvZiBzb21hdGljIGFueGlldHkgcXVlc3Rpb25uYWlyZXMgd2FzICQuODE0JCwgaW5kaWNhdGluZyBhIGdvb2QgaW50ZXJuYWwgY29uc2lzdGVuY3kuCgojIyMgMy41LiBDb3JyZWxhdGlvbnMKClRoaXMgc3Vic2VjdGlvbiBjb25kdWN0cyBjb3JyZWxhdGlvbiBhbmFseXNlcyBiZXR3ZWVuIFVGIG1lYXN1cmVzIGFuZCBzcGVha2luZyBhbnhpZXR5LiBCZWZvcmUgdGhlIGFuYWx5c2VzLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY2FsY3VsYXRlcyB0aHJlZSBhbnhpZXR5IHNjb3JlcyBieSBzdW1taW5nIGl0ZW1zIGFuZCBqb2lucyB0aGUgdHdvIGRhdGFmcmFtZXMuCgpgYGB7cn0KZGZfcXVlc3Rpb25uYWlyZV90aWR5ICU+JQogIGdyb3VwX2J5KHBhcnRpY2lwYW50X2lkKSAlPiUKICBzdW1tYXJpemUoCiAgICBjb2duaXRpdmVfYW54aWV0eSA9IHN1bSgKICAgICAgY29nbml0aXZlX2FueGlldHlfMSwgY29nbml0aXZlX2FueGlldHlfMiwgY29nbml0aXZlX2FueGlldHlfMwogICAgKSwKICAgIHNvbWF0aWNfYW54aWV0eSA9IHN1bSgKICAgICAgc29tYXRpY19hbnhpZXR5XzEsIHNvbWF0aWNfYW54aWV0eV8yLCBzb21hdGljX2FueGlldHlfMwogICAgKSwKICAgIGJlaGF2aW9yYWxfYW54aWV0eSA9IHN1bSgKICAgICAgYmVoYXZpb3JhbF9hbnhpZXR5XzEsIGJlaGF2aW9yYWxfYW54aWV0eV8yLCBiZWhhdmlvcmFsX2FueGlldHlfMwogICAgKQogICkgJT4lIAogIGlubmVyX2pvaW4oCiAgICBkZl91Zl90aWR5LCBieSA9ICJwYXJ0aWNpcGFudF9pZCIKICApIC0+IGRmX3VmX2FueGlldHkKCmRmX3VmX2FueGlldHkKYGBgCgojIyMjIDMuNS4xLiBDb3JyZWxhdGlvbnMgQW1vbmcgQW54aWV0eSBTY29yZXMKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBnZW5lcmF0ZXMgYSBjb3JyZWxhdGlvbiBtYXRyaXggb2YgdGhyZWUgYW54aWV0eSBzY29yZXMuCgpgYGB7cn0KZGZfdWZfYW54aWV0eSAlPiUKICBzZWxlY3QoCiAgICBjb2duaXRpdmVfYW54aWV0eSwKICAgIHNvbWF0aWNfYW54aWV0eSwKICAgIGJlaGF2aW9yYWxfYW54aWV0eQogICkgJT4lCiAgY2hhcnQuQ29ycmVsYXRpb24oaGlzdG9ncmFtID0gVCwgbWV0aG9kID0gInBlYXJzb24iLCBwY2ggPSAxOSkKYGBgCgpUaGUgcmVzdWx0IHNob3dlZCB0aGF0IHNpZ25pZmljYW50IHN0cm9uZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIGNvZ25pdGl2ZSBhbmQgc29tYXRpYyBhbnhpZXR5ICgkcj0uNzgkKS4gSW4gYWRkaXRpb24sIHRoZXJlIHdhcyBzbGlnaHRseSBzaWduaWZpY2FudCBtZWRpdW0gY29ycmVsYXRpb24gYmV0d2VlbiBzb21hdGljIGFuZCBiZWhhdmlvcmFsIGFueGlldHkgKCRyPS41OSQpLiBNZWFud2hpbGUsIHRoZXJlIHdhcyBzbWFsbCBjb3JyZWxhdGlvbiBiZXR3ZWVuIGNvZ25pdGl2ZSBhbmQgYmVoYXZpb3JhbCBhbnhpZXR5ICgkcj0uNDgkKSwgYnV0IHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSB3YXMgbm90IGZvdW5kLgoKIyMjIyAzLjUuMi4gQ29ycmVsYXRpb25zIEJldHdlZW4gVUYgTWVhc3VyZXMgYW5kIENvZ25pdGl2ZSBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgZ2VuZXJhdGVzIGEgY29ycmVsYXRpb24gbWF0cml4IG9mIFVGIG1lYXN1cmVzIGFuZCBjb2duaXRpdmUgYW54aWV0eS4KCmBgYHtyfQpkZl91Zl9hbnhpZXR5ICU+JQogIHNlbGVjdCgtYygKICAgIHBhcnRpY2lwYW50X2lkLCAKICAgIHNvbWF0aWNfYW54aWV0eSwgCiAgICBiZWhhdmlvcmFsX2FueGlldHkKICApKSAlPiUKICBjaGFydC5Db3JyZWxhdGlvbihoaXN0b2dyYW0gPSBULCBtZXRob2QgPSAicGVhcnNvbiIsIHBjaCA9IDE5KQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIHNpZ25pZmljYW50IGxhcmdlIGNvcnJlbGF0aW9uIGJldHdlZW4gY29nbml0aXZlIGFueGlldHkgYW5kIEVDUFIsIHN1Z2dlc3RpbmcgdGhhdCBwYXJ0aWNpcGFudHMgcHJvZHVjZWQgZW5kLWNsYXVzZSBwYXVzZXMgbW9yZSBmcmVxdWVudGx5IHdoZW4gY29nbml0aXZlIGFueGlldHkgd2FzIGxvd2VyLgoKIyMjIyAzLjUuMy4gQ29ycmVsYXRpb25zIEJldHdlZW4gVUYgTWVhc3VyZXMgYW5kIFNvbWF0aWMgQW54aWV0eQoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGdlbmVyYXRlcyBhIGNvcnJlbGF0aW9uIG1hdHJpeCBvZiBVRiBtZWFzdXJlcyBhbmQgc29tYXRpYyBhbnhpZXR5LgoKYGBge3J9CmRmX3VmX2FueGlldHkgJT4lCiAgc2VsZWN0KC1jKAogICAgcGFydGljaXBhbnRfaWQsIAogICAgY29nbml0aXZlX2FueGlldHksIAogICAgYmVoYXZpb3JhbF9hbnhpZXR5CiAgKSkgJT4lCiAgY2hhcnQuQ29ycmVsYXRpb24oaGlzdG9ncmFtID0gVCwgbWV0aG9kID0gInBlYXJzb24iLCBwY2ggPSAxOSkKYGBgCgpUaGUgcmVzdWx0IGRpZCBub3Qgc2hvdyBzaWduaWZpY2FudCBjb3JyZWxhdGlvbnMgYmV0d2VlbiBzb21hdGljIGFueGlldHkgYW5kIFVGIG1lYXN1cmVzLgoKIyMjIyAzLjUuNC4gQ29ycmVsYXRpb25zIEJldHdlZW4gVUYgTWVhc3VyZXMgYW5kIEJlaGF2aW9yYWwgQW54aWV0eQoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGdlbmVyYXRlcyBhIGNvcnJlbGF0aW9uIG1hdHJpeCBvZiBVRiBtZWFzdXJlcyBhbmQgYmVoYXZpb3JhbCBhbnhpZXR5LgoKYGBge3J9CmRmX3VmX2FueGlldHkgJT4lCiAgc2VsZWN0KC1jKAogICAgcGFydGljaXBhbnRfaWQsIAogICAgY29nbml0aXZlX2FueGlldHksIAogICAgc29tYXRpY19hbnhpZXR5CiAgKSkgJT4lCiAgY2hhcnQuQ29ycmVsYXRpb24oaGlzdG9ncmFtID0gVCwgbWV0aG9kID0gInBlYXJzb24iLCBwY2ggPSAxOSkKYGBgCgpUaGUgcmVzdWx0IGlkZW50aWZpZWQgc2lnbmlmaWNhbnQgbGFyZ2UgY29ycmVsYXRpb25zIGJldHdlZW4gYmVoYXZpb3JhbCBhbnhpZXR5IGFuZCBNQ1BEICgkcj0tLjc2JCkgYW5kIEVDUEQgKCRyPS43OSQpLCBzdWdnZXN0aW5nIHRoYXQgcGFydGljaXBhbnRzIHdobyBwZXJjZWl2ZWQgbG93ZXIgYmVoYXZpb3JhbCBhbnhpZXR5IGdlbmVyYXRlIGxvbmdlciBNQ1BEIGFuZCBFQ1BELgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyA0LiBSZWdyZXNzaW9uIEFuYWx5c2VzCgojIyMgNC4xLiBTRiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBBUiBhbmQgc3BlYWtpbmcgYW54aWV0eS4KCmBgYHtyfQptb2RlbF9hciA8LSBsbSgKICBhcnRpY3VsYXRpb25fcmF0ZSB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9hciwgZGlnaXRzID0gMykKYGBgCgpUaGUgcmVzdWx0IGRpZCBub3Qgc2hvdyBzaWduaWZpY2FudCByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aHJlZSBhbnhpZXR5IHNjb3JlcyBhbmQgQVIuCgpUbyBleGFtaW5lIHRoZSByZWxpYWJpbGl0eSBvZiB0aGUgY3VycmVudCBtb2RlbCwgdGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIGNvbmR1Y3RzIHBvc3QtaG9jIGFuYWx5c2lzIG9mIHJlZ3Jlc3Npb24gYXNzdW1wdGlvbnMuCgpgYGB7cn0KY2hlY2tfbW9kZWwobW9kZWxfYXIpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgcmVsaWFibGUuCgojIyMgNC4yLiBCREYgXH4gU3BlYWtpbmcgQW54aWV0eQoKIyMjIyA0LjIuMS4gTUNQUiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBNQ1BSIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX21jcHIgPC0gbG0oCiAgbWlkX2NsYXVzZV9wYXVzZV9yYXRpbyB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9tY3ByLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgZGlkIG5vdCBzaG93IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRocmVlIGFueGlldHkgc2NvcmVzIGFuZCBNQ1BSLgoKVG8gZXhhbWluZSB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIGN1cnJlbnQgbW9kZWwsIHRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25kdWN0cyBwb3N0LWhvYyBhbmFseXNpcyBvZiByZWdyZXNzaW9uIGFzc3VtcHRpb25zLgoKYGBge3J9CmNoZWNrX21vZGVsKG1vZGVsX21jcHIpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgbGVzcyByZWxpYWJsZSBiZWNhdXNlIHRoZSBtb2RlbCBjb3VsZCBiZSBhZmZlY3RlZCBieSBhbiBvdXRsaWVyLgoKIyMjIyA0LjIuMi4gRUNQUiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBFQ1BSIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX2VjcHIgPC0gbG0oCiAgZW5kX2NsYXVzZV9wYXVzZV9yYXRpbyB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9lY3ByLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIHNsaWdodGx5IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGNvZ25pdGl2ZSBhbnhpZXR5IGFuZCBFQ1BSICgkcD0uMDgxJCkuIFRoZSBzbG9wZSB3YXMgJC0uMDAzJCBhbmQgc3VnZ2VzdGVkIHRoYXQgRUNQUiBkZWNyZWFzZWQgJC4wMDMkIHdoZW4gY29nbml0aXZlIGFueGlldHkgaW5jcmVhc2VkICQxJC4KClRvIGV4YW1pbmUgdGhlIHJlbGlhYmlsaXR5IG9mIHRoZSBjdXJyZW50IG1vZGVsLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uZHVjdHMgcG9zdC1ob2MgYW5hbHlzaXMgb2YgcmVncmVzc2lvbiBhc3N1bXB0aW9ucy4KCmBgYHtyfQpjaGVja19tb2RlbChtb2RlbF9lY3ByKQpgYGAKClRoZSByZXN1bHRzIHN1Z2dlc3RlZCB0aGF0IHRoZSBjdXJyZW50IG1vZGVsIGNvdWxkIGJlIHJlbGlhYmxlLgoKIyMjIyA0LjIuMy4gTUNQRCBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBNQ1BEIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX21jcGQgPC0gbG0oCiAgbWlkX2NsYXVzZV9wLmR1ciB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9tY3BkLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIGEgc2lnbmlmaWNhbnQgbGluayBiZXR3ZWVuIGJlaGF2aW9yYWwgYW54aWV0eSBhbmQgTUNQRCAoJHA9LjAyNSQpLiBUaGUgc2xvcGUgd2FzICQtLjA3NCQsIHN1Z2dlc3RpbmcgdGhhdCBNQ1BEIGJlY2FtZSAkLjA3NCQgc2hvcnRlciB3aGVuIGJlaGF2aW9yYWwgYW54aWV0eSBzY29yZSBpbmNyZWFzZWQgJDEkLgoKVG8gZXhhbWluZSB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIGN1cnJlbnQgbW9kZWwsIHRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25kdWN0cyBwb3N0LWhvYyBhbmFseXNpcyBvZiByZWdyZXNzaW9uIGFzc3VtcHRpb25zLgoKYGBge3J9CmNoZWNrX21vZGVsKG1vZGVsX21jcGQpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgcmVsaWFibGUuCgojIyMjIDQuMi40LiBFQ1BEIFx+IFNwZWFraW5nIEFueGlldHkKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25zdHJ1Y3RzIGEgcmVncmVzc2lvbiBtb2RlbCBiZXR3ZWVuIEFSIGFuZCBzcGVha2luZyBhbnhpZXR5LgoKYGBge3J9Cm1vZGVsX2VjcGQgPC0gbG0oCiAgZW5kX2NsYXVzZV9wLmR1ciB+IGNvZ25pdGl2ZV9hbnhpZXR5ICsgc29tYXRpY19hbnhpZXR5ICsgYmVoYXZpb3JhbF9hbnhpZXR5LAogIGRmX3VmX2FueGlldHkKKQpgYGAKClRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBzaG93cyB0aGUgcmVzdWx0LgoKYGBge3J9CnRhYl9tb2RlbChtb2RlbF9lY3BkLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgc2hvd2VkIGEgc2lnbmlmaWNhbnQgbGluayBiZXR3ZWVuIGJlaGF2aW9yYWwgYW54aWV0eSBhbmQgTUNQRCAoJHA9LjAyMCQpLiBUaGUgc2xvcGUgd2FzICQtLjA3MiQsIHN1Z2dlc3RpbmcgdGhhdCBFQ1BEIGJlY2FtZSAkLjA3MiQgc2hvcnRlciB3aGVuIGJlaGF2aW9yYWwgYW54aWV0eSBzY29yZSBpbmNyZWFzZWQgJDEkLgoKVG8gZXhhbWluZSB0aGUgcmVsaWFiaWxpdHkgb2YgdGhlIGN1cnJlbnQgbW9kZWwsIHRoZSBmb2xsb3dpbmcgY29kZSBibG9jayBjb25kdWN0cyBwb3N0LWhvYyBhbmFseXNpcyBvZiByZWdyZXNzaW9uIGFzc3VtcHRpb25zLgoKYGBge3J9CmNoZWNrX21vZGVsKG1vZGVsX2VjcGQpCmBgYAoKVGhlIHJlc3VsdHMgc3VnZ2VzdGVkIHRoYXQgdGhlIGN1cnJlbnQgbW9kZWwgY291bGQgYmUgcmVsaWFibGUuCgojIyMgNC4zLiBSRiBcfiBTcGVha2luZyBBbnhpZXR5CgpUaGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uc3RydWN0cyBhIHJlZ3Jlc3Npb24gbW9kZWwgYmV0d2VlbiBEUiBhbmQgc3BlYWtpbmcgYW54aWV0eS4KCmBgYHtyfQptb2RlbF9kciA8LSBsbSgKICBkaXNmbHVlbmN5X3JhdGlvIH4gY29nbml0aXZlX2FueGlldHkgKyBzb21hdGljX2FueGlldHkgKyBiZWhhdmlvcmFsX2FueGlldHksCiAgZGZfdWZfYW54aWV0eQopCmBgYAoKVGhlIGZvbGxvd2luZyBjb2RlIGJsb2NrIHNob3dzIHRoZSByZXN1bHQuCgpgYGB7cn0KdGFiX21vZGVsKG1vZGVsX2RyLCBkaWdpdHMgPSAzKQpgYGAKClRoZSByZXN1bHQgZGlkIG5vdCBzaG93IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRocmVlIGFueGlldHkgc2NvcmVzIGFuZCBEUi4KClRvIGV4YW1pbmUgdGhlIHJlbGlhYmlsaXR5IG9mIHRoZSBjdXJyZW50IG1vZGVsLCB0aGUgZm9sbG93aW5nIGNvZGUgYmxvY2sgY29uZHVjdHMgcG9zdC1ob2MgYW5hbHlzaXMgb2YgcmVncmVzc2lvbiBhc3N1bXB0aW9ucy4KCmBgYHtyfQpjaGVja19tb2RlbChtb2RlbF9kcikKYGBgCgpUaGUgcmVzdWx0cyBzdWdnZXN0ZWQgdGhhdCB0aGUgY3VycmVudCBtb2RlbCBjb3VsZCBiZSBsZXNzIHJlbGlhYmxlIGJlY2F1c2UgdGhlIG1vZGVsIGNvdWxkIGJlIGFmZmVjdGVkIGJ5IGFuIG91dGxpZXIuCgojIyMgCg==